#include "shorttcpclient.h"
#include "Main/global.h"


ShortTcpClient::ShortTcpClient(QObject *parent) : QObject(parent)
{
    m_tcpClient = std::make_shared<QTcpSocket>(this);
}

bool ShortTcpClient::Init(const QString qsIP, int nPort)
{
    //    connect(m_tcpClient.get(), SIGNAL(readyRead()), this, SLOT(ReadData()));
    connect(m_tcpClient.get(), SIGNAL(error(QAbstractSocket::SocketError)),
            this, SLOT(ReadError(QAbstractSocket::SocketError)));

    m_qsIp = qsIP;
    m_nPort = nPort;


    return true;
}

int ShortTcpClient::TransForNormal(const PACKET_INFO pktInfo,const std::string& sReq, std::string& sRsp, QString& qsErrMsg)
{
    if (CHANNEL_TRADE == pktInfo.nChannel)
        m_tradeChl.SetSession( Global::Instance()->m_qsSessionID.toStdString() );
    else if (CHANNEL_RISK == pktInfo.nChannel)
        m_tradeChl.SetSession( "1100002894");

    m_tcpClient->abort();
    m_tcpClient->connectToHost(m_qsIp, m_nPort);
    if (!m_tcpClient->waitForConnected(2000))  // 连接成功则进入if{}
    {
        qDebug()<< "waitForConnected:连接失败:"<<m_qsIp<<m_nPort;
        qsErrMsg = "连接失败";
        return E_TRANS_CONNECT_FAIL;
    }

    Global::Instance()->GenerateReqSeqno();
    //    sprintf(Global::Instance()->gReqHead.seq_no,"%s", "995ae290");   //test
    std::string sSend = Global::Instance()->gReqHead.ToString();
    sSend += sReq;

    std::shared_ptr<char> sendEnBuf;

    qDebug()<< "发送请求:"<<sSend.c_str();
    int nSendLen = PreSendHandle(sendEnBuf, sSend, pktInfo);

    qint64 nRet = m_tcpClient->write(sendEnBuf.get(), nSendLen);
    qDebug()<<"nRet:"<<nRet<<" nSendLen:"<<nSendLen;//<<" "<<sendEnBuf.get();

    if (!m_tcpClient->waitForBytesWritten())
    {
        qDebug()<< "发送请求失败";
        m_tcpClient->close();
        qsErrMsg = "发送请求失败";
        return E_TRANS_SEND_FAIL;
    }

    QByteArray receiveBuffer;
    //    int iCount = 0;
    if (m_tcpClient->waitForReadyRead(3000))
    {
        //        qDebug()<<"bytesAvailable:"<<iCount++;
        if (m_tcpClient->bytesAvailable())
        {
            receiveBuffer += m_tcpClient->readAll();
        }
    }
    else
    {
        qsErrMsg = "接收响应超时";
        m_tcpClient->close();
        return E_TRANS_RECV_TIMEOUT;
    }

    if (receiveBuffer.size() > 0)
    {
        SufRecvHandle(receiveBuffer.constData(), receiveBuffer.size(), sRsp,pktInfo);
        //        qDebug()<< "响应1:"<< QString::fromStdString(sRsp);
        qDebug()<< "响应2:"<< QString::fromLocal8Bit(sRsp.c_str());
    }
    //    sRsp = receiveBuffer.constData();

    m_tcpClient->close();
    return E_TRANS_SUCCESS;
}

int ShortTcpClient::PreSendHandle(std::shared_ptr<char> &sendEnBuf, const std::string sSend, const PACKET_INFO pktInfo)
{
    if (0 == pktInfo.nEncr)
    {
        int nPktLen = sSend.length()+MSGLEN;
        sendEnBuf = std::shared_ptr<char>(new char[nPktLen],std::default_delete<char[]>());
        memset(sendEnBuf.get(),0, nPktLen);

//        char szLenFmt[64] = {0};
//        sprintf(szLenFmt,"%c0%dd",'%',MSGLEN);
//        char szLen[128] = {0};
//        sprintf(szLen,szLenFmt,sSend.length());
        std::string sPkt = Get8BitLength(sSend.length()).c_str() + sSend;
        memcpy(sendEnBuf.get(),sPkt.c_str(), nPktLen);

        return nPktLen;
    }

    if (CHANNEL_AUTH == pktInfo.nChannel)
        return m_auChl.PreSendHandle(sendEnBuf, sSend);
    else if (CHANNEL_TRADE == pktInfo.nChannel ||CHANNEL_RISK == pktInfo.nChannel)
    {
        std::string sPkt = Get8BitLength(sSend.length()) + sSend;
        return m_tradeChl.PreSendHandle(sendEnBuf, sPkt);
    }

    return 0;
}

int ShortTcpClient::SufRecvHandle(const char *pRecvBuf, unsigned int ulLen, std::string &sRsp, const PACKET_INFO pktInfo)
{
    if (0 == pktInfo.nEncr)
    {
        sRsp.assign(pRecvBuf, ulLen);
    }

    if (CHANNEL_AUTH == pktInfo.nChannel)
        return m_auChl.SufRecvHandle(pRecvBuf, ulLen, sRsp);
    else if (CHANNEL_TRADE == pktInfo.nChannel || CHANNEL_RISK == pktInfo.nChannel)
        return m_tradeChl.SufRecvHandle(pRecvBuf, ulLen, sRsp);

    return 0;
}

void ShortTcpClient::ReadData()
{
    QByteArray buffer = m_tcpClient->readAll();
    if(!buffer.isEmpty())
    {
        qDebug()<< "ReadData:"<<buffer;
    }
}

void ShortTcpClient::ReadError(QAbstractSocket::SocketError socketError)
{
    switch(socketError)
    {
    //RemoteHostClosedError为远处主机关闭了连接时发出的错误信号
    case QAbstractSocket::RemoteHostClosedError :
        qDebug() << "远处主机关闭了连接时发出的错误";
        break;
    default : qDebug() << m_tcpClient->errorString();
    }
}
